package com.chunfen.wx.wa.config;

import com.alibaba.dubbo.config.AbstractInterfaceConfig;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProviderConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.ReferenceBean;
import com.alibaba.dubbo.config.spring.ServiceBean;
import com.chunfen.wx.wa.config.prop.DubboProp;
import com.chunfen.wx.wa.mapper.UserMapper;
import com.chunfen.wx.wa.service.UserService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DubboConfig {

    @Autowired
    private DubboProp dubboProp;

    @Autowired
    private UserService userService;


    private <T> ReferenceBean<T> referenceBean(Class<T> clazz, String version) {
        return referenceBean(clazz, version, 3);
    }

    private <T> ReferenceBean<T> referenceBean(Class<T> clazz, String version, int retries) {
       return referenceBean(clazz, version, retries, 10000);
    }

    private <T> ReferenceBean<T> referenceBean(Class<T> clazz, String version, int retries, int timeout) {
        ReferenceBean<T> referenceBean = new ReferenceBean<>();

        referenceBean.setRegistry(registry());
        referenceBean.setInterface(clazz);
        referenceBean.setVersion(version);
        referenceBean.setRetries(retries < 0 ? 3 : retries);
        referenceBean.setTimeout(timeout < 0 ? 10000 : timeout);

        return referenceBeanInitAndCheck(referenceBean);
    }

    private <T> ReferenceBean<T> referenceBeanInitAndCheck(ReferenceBean<T> referenceBean) {
        referenceBean.setInit(dubboProp.isInit());
        referenceBean.setCheck(dubboProp.isCheck());
        return  referenceBean;
    }


    private <T> ServiceBean<T> serviceBean(T clazz, String version) {
        return serviceBean(clazz, version, 10000);
    }

    private <T> ServiceBean<T> serviceBean(T clazz, String version, int timeout) {
        ServiceBean<T> serviceBean = new ServiceBean<>();
        serviceBean.setInterface(clazz.getClass().getInterfaces()[0]);
        serviceBean.setVersion(version);
        serviceBean.setRef(clazz);
        serviceBean.setRegistry(registry());

        serviceBean.setTimeout(timeout < 0 ? 10000 : timeout);

        return serviceBean;
    }

    @Bean
    public ServiceBean<UserService> userServiceServiceBean() {
        return serviceBean(userService, "1.0");
    }

    @Bean
    public ApplicationConfig dubboApplication() {
        ApplicationConfig application = new ApplicationConfig();
        application.setName(dubboProp.getApplicationName());
        application.setVersion(dubboProp.getAppVersion());
        return application;
    }

    @Bean
    public RegistryConfig registry() {
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress(dubboProp.getZkAddress());
        registry.setProtocol("zookeeper");
        return registry;
    }

//    @Bean
//    public ProviderConfig providerConfig() {
//        ProviderConfig providerConfig = new ProviderConfig();
//        providerConfig.setTimeout(3000);
//        return providerConfig;
//    }
}